use crate::error::Result;
use crate::models::CrawledData;
use csv::Writer;
use serde_json;
use std::fs::File;
use std::path::Path;

pub struct ExportManager;

impl ExportManager {
    pub async fn export_to_csv(data: &[CrawledData], file_path: &Path) -> Result<()> {
        let file = File::create(file_path)?;
        let mut writer = Writer::from_writer(file);
        
        // 写入表头
        writer.write_record(&[
            "ID", "平台", "数据类型", "标题", "内容", "作者", "作者ID",
            "链接", "点赞数", "评论数", "分享数", "浏览数", "发布时间", "爬取时间", "关键词"
        ])?;
        
        // 写入数据
        for item in data {
            writer.write_record(&[
                &item.id,
                &item.platform,
                &item.data_type,
                &item.title,
                item.content.as_deref().unwrap_or(""),
                &item.author,
                &item.author_id,
                &item.url,
                &item.like_count.to_string(),
                &item.comment_count.to_string(),
                &item.share_count.to_string(),
                &item.view_count.to_string(),
                &item.created_at.to_rfc3339(),
                &item.crawled_at.to_rfc3339(),
                &item.keywords,
            ])?;
        }
        
        writer.flush()?;
        Ok(())
    }
    
    pub async fn export_to_json(data: &[CrawledData], file_path: &Path) -> Result<()> {
        let json = serde_json::to_string_pretty(data)?;
        tokio::fs::write(file_path, json).await?;
        Ok(())
    }
    
    pub async fn export_to_excel(data: &[CrawledData], file_path: &Path) -> Result<()> {
        // 这里可以使用 rust_xlsxwriter 或其他 Excel 库
        // 为了简化，我们先导出为 CSV 格式
        Self::export_to_csv(data, file_path).await
    }
}

#[allow(dead_code)]
pub struct NotificationManager;

impl NotificationManager {
    #[allow(dead_code)]
    pub async fn send_desktop_notification(title: &str, message: &str) -> Result<()> {
        // 这里可以使用 notify-rust 或其他通知库
        log::info!("Desktop notification: {} - {}", title, message);
        Ok(())
    }
    
    #[allow(dead_code)]
    pub async fn send_email_notification(
        to: &str,
        subject: &str,
        body: &str,
        _smtp_server: &str,
    ) -> Result<()> {
        // 这里可以使用 lettre 或其他邮件库
        log::info!("Email notification to {}: {} - {}", to, subject, body);
        Ok(())
    }
}

pub struct SystemUtils;

impl SystemUtils {
    pub fn get_system_info() -> crate::models::SystemInfo {
        crate::models::SystemInfo {
            os: std::env::consts::OS.to_string(),
            arch: std::env::consts::ARCH.to_string(),
            version: env!("CARGO_PKG_VERSION").to_string(),
            memory_usage: "256MB".to_string(), // 这里可以使用 sysinfo 库获取真实数据
            cpu_usage: 15.5,
            disk_usage: "2.3GB / 100GB".to_string(),
        }
    }
    
    pub async fn open_folder(path: &str) -> Result<()> {
        #[cfg(target_os = "windows")]
        {
            std::process::Command::new("explorer")
                .arg(path)
                .spawn()?;
        }
        
        #[cfg(target_os = "macos")]
        {
            std::process::Command::new("open")
                .arg(path)
                .spawn()?;
        }
        
        #[cfg(target_os = "linux")]
        {
            std::process::Command::new("xdg-open")
                .arg(path)
                .spawn()?;
        }
        
        Ok(())
    }
    
    #[allow(dead_code)]
    pub fn format_file_size(bytes: u64) -> String {
        const UNITS: &[&str] = &["B", "KB", "MB", "GB", "TB"];
        let mut size = bytes as f64;
        let mut unit_index = 0;
        
        while size >= 1024.0 && unit_index < UNITS.len() - 1 {
            size /= 1024.0;
            unit_index += 1;
        }
        
        format!("{:.2} {}", size, UNITS[unit_index])
    }
    
    #[allow(dead_code)]
    pub fn validate_url(url: &str) -> bool {
        url.starts_with("http://") || url.starts_with("https://")
    }
    
    #[allow(dead_code)]
    pub fn sanitize_filename(filename: &str) -> String {
        filename
            .chars()
            .map(|c| match c {
                '<' | '>' | ':' | '"' | '/' | '\\' | '|' | '?' | '*' => '_',
                _ => c,
            })
            .collect()
    }
}